package controllers

import (
	"encoding/json"
	"fmt"
	"gitchina/kly_service/errors"
	"gitchina/kly_service/models"
	"gitchina/kly_service/util"
	"github.com/astaxie/beego"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
)

var (
	IMG_UPLOAD_PROTO_CUSTOM = 1
	IMG_UPLOAD_PROTO_RFC    = 2
)

type ImageController struct {
	beego.Controller
}

func init() {
	dir := beego.AppConfig.String("imageDir")
	models.InitImageDir(dir)
}

// @router /101002 [post]
func (m *ImageController) UploadImage() {
	var ext string
	var contentType string
	var imgProperties string
	var img models.Image
	var mbrId models.ID

	if val := m.Ctx.Input.GetData("mbrId"); val != nil {
		mbrId = models.ID(val.(string))
	} else {
		mbrId = ""
	}

	maxImageSize := beego.AppConfig.DefaultInt("maxImageSize", 1048576)
	dir := beego.AppConfig.String("imageDir")
	cdn := beego.AppConfig.String("imageCdn")

	if imgProperties = m.Ctx.Request.Header.Get("image-properties"); imgProperties == "" {
		m.Data["json"] = models.NewFailResponse(errors.New(errors.MSG_Image_Invalid_Properties))
		m.ServeJSON()
		return
	}

	var rq models.UploadImageRQ
	err := json.Unmarshal([]byte(imgProperties), &rq)
	if err != nil {
		m.Data["json"] = models.NewFailResponse(errors.New(errors.MSG_Image_Invalid_Properties))
		m.ServeJSON()
		return
	}

	var imageData []byte
	if rq.Proto == IMG_UPLOAD_PROTO_CUSTOM {
		imageData = m.Ctx.Input.RequestBody
		contentType = m.Ctx.Request.Header.Get("Content-Type")
	} else {
		f, h, err := m.GetFile("uploadimg")
		contentType = h.Header.Get("Content-Type")
		if err != nil {
			util.GetLogger().Error("[controller:UploadImage] - get file error: %s", err.Error())
			m.Data["json"] = models.NewFailResponse(errors.New(errors.MSG_Image_Not_Found))
			m.ServeJSON()
		} else {
			imageData, err = ioutil.ReadAll(f)
			if err != nil {
				util.GetLogger().Error("[controller:UploadImage] - read file error: %s", err.Error())
				m.Data["json"] = models.NewFailResponse(errors.New(errors.MSG_Image_Not_Found))
				m.ServeJSON()
			}
		}
	}

	if len(imageData) > maxImageSize {
		util.GetLogger().Error("[controller:UploadImage] - unexpected image size: %d or size > %d", len(imageData), maxImageSize)
		m.Data["json"] = models.NewFailResponse(errors.New(errors.MSG_Image_Invalid_Size))
		m.ServeJSON()
		return
	}

	if contentType == "image/jpg" {
		ext = "jpg"
	} else if contentType == "image/jpeg" {
		ext = "jpg"
	} else if contentType == "image/png" {
		ext = "png"
	} else {
		util.GetLogger().Error("[controller:UploadImage] - unexpected image ext: %s", contentType)
		m.Data["json"] = models.NewFailResponse(errors.New(errors.MSG_Image_Invalid_Ext))
		m.ServeJSON()
		return
	}

	rq.MbrId = mbrId
	rq.Data = imageData
	rq.RootDir = dir
	rq.Ext = ext
	rq.Cdn = cdn

	url, err := img.Upload(&rq)
	if err != nil {
		m.Data["json"] = models.NewFailResponse(err)
	} else {
		m.Data["json"] = models.NewOkResponse(url)
	}
	m.ServeJSON()
}

// @router /109004 [post]
func (m *ImageController) AddAdPic() {
	m.UploadImage()
}

// @router /* [get]
func (m *ImageController) Get() {
	fileName := strings.Replace(m.Ctx.Input.URL(), "/v1/image/", "", 1)
	dir := beego.AppConfig.String("imageDir")
	file, err := os.Open(fmt.Sprintf("%s%s", dir, fileName))
	if err == nil {
		img, _ := ioutil.ReadAll(file)
		w := m.Ctx.ResponseWriter
		w.Header().Set("Content-Type", "image/jpg")
		w.Header().Set("Content-Length", strconv.Itoa(len(img)))
		w.Write(img)
	} else {
		fmt.Println(err.Error())
	}
}
